use crate::{
    models::permission::{LoginForm, Token, UserInfo},
    reply::{Code, Reply},
    state::State,
};
use entity::{prelude::Registry, registry};
use poem::{
    handler,
    web::{Data, Json},
};
use sea_orm::{ColumnTrait, EntityTrait, QueryFilter};
use sha2::Digest;

#[handler]
pub async fn login(
    Data(State {
        db, pswd_hasher, ..
    }): Data<&State>,
    Json(login_form): Json<LoginForm>,
) -> Reply<Token> {
    Registry::find()
        .filter(registry::Column::Username.eq(login_form.username.as_str()))
        .one(db)
        .await
        .unwrap()
        .map_or_else(
            || Reply::new().code(Code::NoItem).msg(login_form.username),
            |reg| {
                let hashed_pswd = format!(
                    "{:x}",
                    pswd_hasher
                        .as_ref()
                        .clone()
                        .chain_update(&login_form.password)
                        .finalize()
                );

                if reg.password == hashed_pswd {
                    let token = codec::gen(reg.username).unwrap();

                    Reply::new().data(Token { token })
                } else {
                    Reply::new().code(Code::WrongPassword).msg(reg.username)
                }
            },
        )
}

#[handler]
pub fn info() -> Reply<UserInfo> {
    Reply::new().data(UserInfo { roles: ["admin"] })
}
